trigger SetLastPlannedDate on CallPlan__c (before update,before insert,after delete) {

//10-28 日修改，用MAP解决FOR循环太多问题
//现存问题：too many script statement
//解决方案：用MAP去代替for循环的工作，减低重复循环代码量

//实现的功能有：为医院和HCP添加最后拜访和最后计划日期
//                          为HCP添加拜访月份和历史拜访月份
//                          填入拜访月份时，判断字段里面如果有过期的日期，提取出来，放入历史拜访月份，只放一个
//                          填入历史拜访月份时，判断如果历史拜访月份已满，则删除最早起的拜访月份




List<HCP__c> hcpl=new List<HCP__c>();
  List<Hospital__c> hpl=new List<Hospital__c>();
  List<id> hcpid=new list<id>();
  list<id> hpid=new list<id>();
  list<string> sl=new list<string>();
  list<string> storehl=new list<string>();
  string month;
  integer hlength;
  set<string> hl=new set<string>();
  //定义MAP记录实际拜访日期，key为HCP ID，value为计划拜访日期；
  map<id,date> visitmap=new map<id,date>();
  //定义map记录计划拜访日期，key为HCP ID，value为计划拜访日期；
  map<id,date> planmap=new map<id,date>();
  //定义嵌套map，外部key保存hcp id，内部保存拜访月份和月份拜访次数，key为id+年+月份，value为次数；
  map<string,integer> innerMap=new map<string,integer>();//内部map    
  map<id,map<string,integer>> PlanMonthMap=new map<id,map<string,integer>>();//外部map

  
  if(system.trigger.isinsert||(system.trigger.isupdate)){
  //CallMonth变量用于保存拜访的月份，如果月份为1位数字，则月份前补0；
  string CallMonth;
  
  for (callplan__c t:trigger.new){
    CallMonth=null;
    if(t.callworkingtype__c=='拜访' && t.delete_mark__c==false){
        hcpid.add(t.hcp__c);
    }
    //放入拜访的月份
    if(string.valueof(t.callplandate__c.month()).length()>1){
        callmonth=string.valueof(t.callplandate__c.month());
    }else if(string.valueof(t.callplandate__c.month()).length()==1){
        callmonth='0'+t.callplandate__c.month();
    }
    //将数据放入内部MAP
    if(innerMap.containskey(t.HCP__c+string.valueof(t.callplandate__c.year())+callmonth)){
        innerMap.put(t.HCP__c+string.valueof(t.callplandate__c.year())+callmonth,innerMap.get(t.HCP__c+string.valueof(t.callplandate__c.year())+callmonth)+1);
    }else{
        innerMap.put(t.HCP__c+string.valueof(t.callplandate__c.year())+callmonth,1);
    }
    //将内部MAP放入主MAP；
    PlanMonthMap.put(t.Hcp__c,innerMap);
    
    if(t.callworkingtype__c=='拜访' && t.CallExecutionstatus__c=='是'){
        if(!(visitmap.containskey(t.HCP__c) && visitmap.get(t.hcp__c)>t.callplandate__c)){
            visitmap.put(t.hcp__c,t.callplandate__c);
        }
    }
    if(t.PlanType__c=='计划内' && t.callworkingtype__c=='拜访'){
        if(!(planmap.containskey(t.HCP__c) && planmap.get(t.hcp__c)>t.callplandate__c)){
            planmap.put(t.hcp__c,t.callplandate__c);
        }
    }
  }
  }

  //查询出所有对应HCP
  hcpl=[select id,hospital__c,lastplanneddate__c,lastvisiteddate__c,callPlanMonth_hidden__c,historyCallMonth__c from hcp__c where id in:hcpid];
  
  if(system.trigger.isinsert||system.trigger.isupdate){
  
  //定义医院最后拜访map，key为医院ID，value为拜访日期；
  map<id,date> HosVisitMap=new map<id,date>();
  //定义医院最后计划map，key为医院ID，value为拜访日期；
  map<id,date> HosPlanMap=new map<id,date>();
  
  for(hcp__c h:hcpl){
       
  
       if(h.lastvisiteddate__c<visitmap.get(h.id) || h.lastvisiteddate__c==null){    //更改HCPlastvisiteddate
            h.lastvisiteddate__c=visitmap.get(h.id);
            if(!(hosvisitmap.containskey(h.hospital__c) && hosvisitmap.get(h.hospital__c)>visitmap.get(h.id)) ){
                hosvisitmap.put(h.hospital__c,visitmap.get(h.id));
             }
       }
       if(h.lastplanneddate__c<planmap.get(h.id) || h.lastplanneddate__c==null){   //更改HCPlastplaneddate
            h.lastplanneddate__c=planmap.get(h.id);
            if(!(hosplanmap.containskey(h.hospital__c) && hosplanmap.get(h.hospital__c)>visitmap.get(h.id)) ){
                hosplanmap.put(h.hospital__c,visitmap.get(h.id));
             }
       }
       
       //填入拜访月份&历史拜访月份
       if(system.trigger.isinsert){
           sl.clear();
           hl.clear();
           if(h.callPlanMonth_hidden__c!=null){
                sl=h.callPlanMonth_hidden__c.split(',', 0);
            }
            h.callPlanMonth_hidden__c=null;
            sl.sort();
            if(h.historyCallMonth__c!=null){
                for(string history:h.historyCallMonth__c.split(',',0)){
                    hl.add(history);
                }
            }
            h.historyCallMonth__c='';
            
            for(string m:planmonthmap.get(h.id).keyset()){    //最多两次，一个月一次，跨月的话会有两次
            //    month=m.substring(m.length()-2,m.length());
                for(integer i=0;i<planmonthmap.get(h.id).get(m);i++){    //当月一条拜访计划一次
                    if(i==0){
                        h.callPlanMonth_hidden__c= m.substring(m.length()-4,m.length());
                    }else{
                        h.callPlanMonth_hidden__c+= ','+m.substring(m.length()-4,m.length());
                    }
                }
            }
            for(string s:sl){
          
              if(s!=null && s!='null'){
              if(!((integer.valueof(s.substring(0,2))==integer.valueof(string.valueof(date.today().year()).substring(2,4)) && integer.valueof(s.substring(3,s.length()))<date.today().month())||integer.valueof(s.substring(0,2))<integer.valueof(string.valueof(date.today().year()).substring(2,4)))){           //  if((integer.valueof(s.substring(0,4))==date.today().year() && integer.valueof(s.substring(5,6))<date.today().month())||integer.valueof(s.substring(0,4))<date.today().year())
                   h.callplanMonth_hidden__c+=','+s;
              }else{
                  hl.add(s);
              }
              }
          }
          for(string his:hl){
              if(his!=null&&his!='null'){
              if(h.historyCallMonth__c==''||h.historyCallMonth__c==null){
                  h.historyCallMonth__c=his;
              }else{
                  h.historyCallMonth__c+=','+his;
                }
                
              }
          }
            //string.valueof(cp.callplandate__c.year()).substring(2,4)+month;
            
       }
       hpid.add(h.hospital__c);
  }
  try{
  update hcpl;
  }catch(dmlexception e){

    for(hcp__c h:hcpl){
           hlength=((h.historycallmonth__c.length()-255)/5+1)*5;
           if(hlength>0){
              h.historycallmonth__c=h.historycallmonth__c.substring(hlength,h.historycallmonth__c.length());
            }
      //    system.assert(false,h.historycallmonth__c.length());  
    }
    update hcpl;
  }
  
  hpl=[select id,lastplanneddate__c,lastvisiteddate__c from Hospital__c where id in:hpid];

  for(hospital__c h:hpl){

        if(h.lastvisiteddate__c<hosvisitmap.get(h.id) || h.lastvisiteddate__c==null){
            h.lastvisiteddate__c=hosvisitmap.get(h.id);
        }
        if(h.lastplanneddate__c<hosplanmap.get(h.id) || h.lastplanneddate__c==null){
           h.lastplanneddate__c=hosplanmap.get(h.id);
        }
        
     } 
     update hpl;
  }
 
  
  
 
 
 boolean b;
if(system.trigger.isdelete){
   for (callplan__c t:trigger.old){
    if(t.callworkingtype__c=='拜访'){
        hcpid.add(t.hcp__c);
    }
  }
 for(callplan__c cp:trigger.old){
 if(cp.PlanType__c=='计划内'){
    for(hcp__c h:hcpl){
    b=true;
        if(h.id==cp.hcp__c){
          sl.clear();
          if(h.callPlanMonth_hidden__c!=null){
              sl=h.callPlanMonth_hidden__c.split(',', 0);
          }
            h.callPlanMonth_hidden__c='';
          if(string.valueof(cp.callplandate__c.month()).length()>1){
              month=string.valueof(cp.callplandate__c.month());
          }else if(string.valueof(cp.callplandate__c.month()).length()==1){
              month='0'+cp.callplandate__c.month();
          }
          for(string s:sl){
              if(s==string.valueof(cp.callplandate__c.year()).substring(2,4)+month&&b){
               b=false;
              }else if(s!=null&& s!= 'null'){
              if(h.callplanMonth_hidden__c==''||h.callplanMonth_hidden__c==null){
                  h.callplanMonth_hidden__c=s;
              }else{
                  h.callplanMonth_hidden__c+=','+s;
                }
              }
          }
         
          
     }
 }
 }
 }
 
 update hcpl;



/* 以下为旧的未优化代码；
  List<HCP__c> hcpl=new List<HCP__c>();
  List<Hospital__c> hpl=new List<Hospital__c>();
  List<id> hcpid=new list<id>();
  list<id> hpid=new list<id>();
  list<string> sl=new list<string>();
  list<string> storehl=new list<string>();
  string month;
  integer hlength;
  set<string> hl=new set<string>();
  if(system.trigger.isinsert||system.trigger.isupdate){
  for (callplan__c t:trigger.new){
    if(t.callworkingtype__c=='拜访'){
        hcpid.add(t.hcp__c);
    }
  }
  }
  if(system.trigger.isdelete){
   for (callplan__c t:trigger.old){
    if(t.callworkingtype__c=='拜访'){
        hcpid.add(t.hcp__c);
    }
  }
  }
  hcpl=[select id,hospital__c,lastplanneddate__c,lastvisiteddate__c,callPlanMonth_hidden__c,historyCallMonth__c from hcp__c where id in:hcpid];
  
  if(system.trigger.isinsert||system.trigger.isupdate){
  for(callplan__c cp:trigger.new){
    for(hcp__c h:hcpl){
        if(h.id==cp.hcp__c){
            if(cp.CallExecutionstatus__c=='是' && (h.lastvisiteddate__c<cp.CallPlanDate__c || h.lastvisiteddate__c==null)){    //更改HCPlastvisiteddate
                    h.lastvisiteddate__c=cp.CallPlanDate__c;
                }
            if((h.lastplanneddate__c<cp.CallPlanDate__c || h.lastplanneddate__c==null)&&cp.PlanType__c=='计划内'){   //更改HCPlastplaneddate
                    h.lastplanneddate__c=cp.CallPlanDate__c;
                }

         //填入拜访月份
         if(system.trigger.isinsert){
         
         if(cp.PlanType__c=='计划内'){
          sl.clear();
          hl.clear();
          if(h.callPlanMonth_hidden__c!=null){
              sl=h.callPlanMonth_hidden__c.split(',', 0);
          }
          sl.sort();
          if(h.historyCallMonth__c!=null){
              for(string history:h.historyCallMonth__c.split(',',0)){
                  hl.add(history);
              }
          }
          h.historyCallMonth__c='';
          if(string.valueof(cp.callplandate__c.month()).length()>1){
              month=string.valueof(cp.callplandate__c.month());
          }else if(string.valueof(cp.callplandate__c.month()).length()==1){
              month='0'+cp.callplandate__c.month();
          }
          h.callPlanMonth_hidden__c=string.valueof(cp.callplandate__c.year()).substring(2,4)+month;
         // system.assert(false,h.callPlanMonth_hidden__c);
          for(string s:sl){
          
              if(s!=null && s!='null'){
              if(!((integer.valueof(s.substring(0,2))==integer.valueof(string.valueof(date.today().year()).substring(2,4)) && integer.valueof(s.substring(3,s.length()))<date.today().month())||integer.valueof(s.substring(0,2))<integer.valueof(string.valueof(date.today().year()).substring(2,4)))){           //  if((integer.valueof(s.substring(0,4))==date.today().year() && integer.valueof(s.substring(5,6))<date.today().month())||integer.valueof(s.substring(0,4))<date.today().year())
                   h.callplanMonth_hidden__c+=','+s;
              }else{
                  hl.add(s);
              }
              }
          }
          for(string his:hl){
              storehl.add(his);
          }
          storehl.sort();
          for(string his:storehl){
              if(his!=null&&his!='null'){
              if(h.historyCallMonth__c==''||h.historyCallMonth__c==null){
                  h.historyCallMonth__c=his;
              }else{
                  h.historyCallMonth__c+=','+his;
                }
                
              }
          }
          
          }
       //   system.assert(false,h.callplanmonth_hidden__c);
        }
        }
    hpid.add(h.hospital__c);
    }
  }
  try{
  update hcpl;
  }catch(dmlexception e){
      for(callplan__c cp:trigger.new){
    for(hcp__c h:hcpl){
        if(h.id==cp.hcp__c){
           hlength=((h.historycallmonth__c.length()-255)/5+1)*5;
           if(hlength>0){
              h.historycallmonth__c=h.historycallmonth__c.substring(hlength,h.historycallmonth__c.length());
          }
      //    system.assert(false,h.historycallmonth__c.length());
        
        }
      }
    }
    update hcpl;
  }
  
  hpl=[select id,lastplanneddate__c,lastvisiteddate__c from Hospital__c where id in:hpid];
  
  for(callplan__c cp:trigger.new){
  for(hospital__c h:hpl){
  for(hcp__c hcp:hcpl){
     if(hcp.id==cp.hcp__c && hcp.hospital__c==h.id){
        if(cp.CallExecutionstatus__c=='是' && (h.lastvisiteddate__c<cp.CallPlanDate__c || h.lastvisiteddate__c==null)){
            h.lastvisiteddate__c=cp.CallPlanDate__c;
        }
        if((h.lastplanneddate__c<cp.CallPlanDate__c || h.lastplanneddate__c==null)&&cp.PlanType__c=='计划内'){
           h.lastplanneddate__c=cp.CallPlanDate__c;
        }
       
     }
  }
  }
  }
  update hpl;
  
  
 }
 
 boolean b;
if(system.trigger.isdelete){
 for(callplan__c cp:trigger.old){
 if(cp.PlanType__c=='计划内'){
    for(hcp__c h:hcpl){
    b=true;
        if(h.id==cp.hcp__c){
          sl.clear();
          if(h.callPlanMonth_hidden__c!=null){
              sl=h.callPlanMonth_hidden__c.split(',', 0);
          }
            h.callPlanMonth_hidden__c='';
          if(string.valueof(cp.callplandate__c.month()).length()>1){
              month=string.valueof(cp.callplandate__c.month());
          }else if(string.valueof(cp.callplandate__c.month()).length()==1){
              month='0'+cp.callplandate__c.month();
          }
          for(string s:sl){
              if(s==string.valueof(cp.callplandate__c.year()).substring(2,4)+month&&b){
               b=false;
              }else if(s!=null&& s!= 'null'){
              if(h.callplanMonth_hidden__c==''||h.callplanMonth_hidden__c==null){
                  h.callplanMonth_hidden__c=s;
              }else{
                  h.callplanMonth_hidden__c+=','+s;
                }
              }
          }
         
          
     }
 }
 }
 }
 
 update hcpl;
 }*/
 
 
 }}